package middleware.llvm.instruction;

import middleware.llvm.BasicBlock;
import middleware.llvm.value.IRType;
import middleware.llvm.value.User;
import middleware.llvm.value.Value;

import java.io.PrintStream;

/**
 * 指令的基类
 *
 * @author 杨凯伟
 * @date 2024/10/30
 */
public abstract class Instruction extends User {
    private BasicBlock basicBlock;

    public Instruction(IRType type, Value... operands) {
        super(type, operands);
    }

    public BasicBlock getBasicBlock() {
        return basicBlock;
    }

    public void setBasicBlock(BasicBlock basicBlock) {
        this.basicBlock = basicBlock;
    }

    public  void replaceAllUseWith(Value newValue, boolean needInsert) {
        var idx = basicBlock.getInstructions().indexOf(this);
        if (needInsert) {
            if (newValue instanceof Instruction newInst) {
                basicBlock.getInstructions().set(idx, newInst);
            } else {
                throw new RuntimeException();
            }
        } else {
            basicBlock.getInstructions().remove(idx);
        }

//        for (var use : getUseList()) {//所有均替换承newValue
//            use.getUser().replaceOperand(use.getPos(), newValue);
//        }
        getUseList().forEach(use -> {
            use.getUser().replaceOperand(use.getPos(), newValue);
        });
    }

    @Override
    public String getName() {
        return "%t" + super.getName();
    }

    public abstract void dump(PrintStream out);
}
